#ifndef RTSTDCPP_H
#define RTSTDCPP_H

#include "RtDefines.h"
#include <ctype.h>

//#define RT_DISABLE_MSVCP_DLL

#if defined (_MSC_VER) && defined (_DLL) && defined (RT_DISABLE_MSVCP_DLL)
//  #pragma warning(disable:4273)

  #undef _CRTIMP
  #define _CRTIMP

  #ifdef _DEBUG
    #pragma comment(linker, "/NODEFAULTLIB:LIBCMTD")
    #pragma comment(linker, "/NODEFAULTLIB:MSVCPRTD")
    #pragma comment(lib, "LIBCPMTD")
  #else
    #pragma comment(linker, "/NODEFAULTLIB:LIBCMT")
    #pragma comment(linker, "/NODEFAULTLIB:MSVCPRT")
    #pragma comment(lib, "LIBCPMT")
  #endif // _DEBUG

  #define _USE_ANSI_CPP

#endif // _MSC_VER && _DLL && RT_DISABLE_MSVCP_DLL



//#define RT_IMPLEMENT_VAR_FOR_MSVCP() 
#if _MSC_VER>1200
#undef min
#undef max
#endif
#include <memory>
#include <utility>
#include <algorithm>
#include <utility>

/*
#ifdef _MSC_VER
  #define RT_MIN std::_cpp_min
  #define RT_MAX std::_cpp_max
#else
  #define RT_MIN std::min
  #define RT_MAX std::max
#endif // _MSC_VER
*/
//cg test
#define RT_MAX(a,b)    (((a) > (b)) ? (a) : (b))
#define RT_MIN(a,b)    (((a) < (b)) ? (a) : (b))

#if defined (_MSC_VER) && defined (_DLL) && defined (RT_DISABLE_MSVCP_DLL)
  #include <xiosbase>
  #undef _DLL
  #include <fstream>
  #include <string>
  #include <locale>
//  #include <iostream>
//  #include <strstream>
  #define _DLL

  // Can't include <iostream> that depending on C static library.
  #ifdef _IOSTREAM_
    #error Error: Can not include <iostream> if using RT_DISABLE_MSVCP_DLL.
  #endif // _IOSTREAM_
  #define _IOSTREAM_

#else
    #include <string>
#endif // _MSC_VER && _DLL && RT_DISABLE_MSVCP_DLL

#include <set> 
#include <map>
#include <vector>
#include <list>

#if defined (_MSC_VER) && defined (_DLL) && defined (RT_DISABLE_MSVCP_DLL)
  #undef _CRTIMP
  #define _CRTIMP __declspec(dllimport)
#endif // _MSC_VER && _DLL && RT_DISABLE_MSVCP_DLL



class CRtString : public std::string
{
public:
	typedef std::string SuperType;

public:
	CRtString()
		: SuperType()
	{
	}
	
	CRtString(const char *s)
		: SuperType(s ? s : "")
	{
	}

	CRtString(const wchar_t *s)
		: SuperType(s ? (const char*)s : "", s ? sizeof(wchar_t)*wcslen(s) : 0)
	{
	}

	CRtString(const char *s, SuperType::size_type n)
		: SuperType(s ? s : "", s ? n : 0)
	{
	}

#if defined(RT_WIN32)
	template <class IterType>
	CRtString(IterType s1, IterType s2)
		: SuperType(s1, s2, SuperType::allocator_type())
	{
	}
#else
	CRtString(const char* s1, const char* s2)
		: SuperType(s1, s2 - s1)
	{
	}
#endif

	CRtString(const SuperType &str)
		: SuperType(str)
	{
	}

	CRtString(const CRtString &str)
		: SuperType(str)
	{
	}

	CRtString(SuperType::size_type n, char c)
		: SuperType(n, c, SuperType::allocator_type())
	{
	}

	CRtString& operator = (const char *s)
	{
		SuperType::operator = (s ? s : "");
		return *this;
	}

	CRtString& operator = (const wchar_t *s)
	{
		if (s)
			SuperType::assign((const char*)s, sizeof(wchar_t)*wcslen(s));
		else
			SuperType::operator = ("");

		return *this;
	}

	CRtString& operator = (const CRtString &str)
	{
		SuperType::operator = (str);
		return *this;
	}

	CRtString& operator = (char c)
	{
		SuperType::operator = (c);
		return *this;
	}
};

class CRtIsSpace
{
public:
	int operator() (const char c) {
		return c == ' ';
	}
};

template<class IS> 
void LTrimString(CRtString &aTrim, IS aIs)
{
	LPCSTR pStart = aTrim.c_str();
	LPCSTR pMove = pStart;

	for ( ; *pMove; ++pMove) {
		if (!aIs(*pMove)) {
			if (pMove != pStart) {
				size_t nLen = strlen(pMove);
				aTrim.replace(0, nLen, pMove, nLen);
				aTrim.resize(nLen);
			}
			return;
		}
	}
};

template<class IS> 
void RTrimString(CRtString &aTrim, IS aIs)
{
	if (aTrim.empty())
		return;

	LPCSTR pStart = aTrim.c_str();
	LPCSTR pEnd = pStart + aTrim.length() - 1;
	LPCSTR pMove = pEnd;

	for ( ; pMove >= pStart; --pMove) {
		if (!aIs(*pMove)) {
			if (pMove != pEnd)
				aTrim.resize(pMove - pStart + 1);
			return;
		}
	}
};

template<class IS> 
void TrimString(CRtString &aTrim, IS aIs)
{
	LTrimString(aTrim, aIs);
	RTrimString(aTrim, aIs);
};


#endif // RTSTDCPP_H
